#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
对话框模块

提供各种对话框组件
"""

from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel, 
                             QLineEdit, QPushButton, QDialogButtonBox,
                             QRadioButton, QCheckBox, QSpinBox, QColorDialog,
                             QGroupBox, QFormLayout, QSlider, QComboBox)
from PyQt5.QtGui import QPixmap, QImage, QColor, QIcon, QFont
from PyQt5.QtCore import Qt, QSize

import numpy as np

from src.core.image_processor import ImageProcessor

class RegionSettingsDialog(QDialog):
    """区域设置对话框"""
    
    def __init__(self, region_data=None, parent=None):
        """初始化对话框
        
        参数:
            region_data (tuple): 区域数据 (x, y, w, h, name)
            parent: 父窗口
        """
        super().__init__(parent)
        self.region_data = region_data
        self.bg_color = [255, 255, 255]  # 默认白色背景
        self.bg_threshold = 30  # 默认阈值
        self.enable_bg_removal = False
        self.init_ui()
        
    def init_ui(self):
        """初始化用户界面"""
        self.setWindowTitle("区域设置")
        layout = QVBoxLayout()
        
        # 区域信息
        info_group = QGroupBox("区域信息")
        info_layout = QFormLayout()
        
        # 区域名称 - 使用隐藏字段，不展示给用户
        self.name_edit = QLineEdit()
        if self.region_data and len(self.region_data) > 4:
            # 使用已有名称或生成名称
            name = self.region_data[4]
            self.name_edit.setText(name)
        # 不添加名称字段到表单，隐藏该功能
        
        # 坐标和大小信息
        if self.region_data:
            x, y, w, h = self.region_data[:4]
            self.x_spin = QSpinBox()
            self.x_spin.setRange(0, 9999)
            self.x_spin.setValue(int(x))
            info_layout.addRow("X坐标:", self.x_spin)
            
            self.y_spin = QSpinBox()
            self.y_spin.setRange(0, 9999)
            self.y_spin.setValue(int(y))
            info_layout.addRow("Y坐标:", self.y_spin)
            
            self.w_spin = QSpinBox()
            self.w_spin.setRange(1, 9999)
            self.w_spin.setValue(int(w))
            info_layout.addRow("宽度:", self.w_spin)
            
            self.h_spin = QSpinBox()
            self.h_spin.setRange(1, 9999)
            self.h_spin.setValue(int(h))
            info_layout.addRow("高度:", self.h_spin)
        
        info_group.setLayout(info_layout)
        layout.addWidget(info_group)
        
        # 背景滤除设置
        bg_group = QGroupBox("背景滤除")
        bg_layout = QVBoxLayout()
        
        # 启用背景滤除复选框
        self.bg_check = QCheckBox("启用背景滤除")
        self.bg_check.setChecked(self.enable_bg_removal)
        self.bg_check.stateChanged.connect(self.on_bg_check_changed)
        bg_layout.addWidget(self.bg_check)
        
        # 背景色选择
        color_layout = QHBoxLayout()
        # 背景色标签和值
        color_layout.addWidget(QLabel("背景色 (RGB):"))
        self.color_value_edit = QLineEdit()
        self.color_value_edit.setPlaceholderText("255,255,255")
        self.color_value_edit.setText(f"{self.bg_color[0]},{self.bg_color[1]},{self.bg_color[2]}")
        self.color_value_edit.textChanged.connect(self.on_color_text_changed)
        color_layout.addWidget(self.color_value_edit)
        
        # 颜色按钮
        self.color_button = QPushButton()
        self.color_button.setFixedSize(50, 25)
        self.update_color_button()
        self.color_button.clicked.connect(self.choose_color)
        color_layout.addWidget(self.color_button)
        
        # 从图像选择按钮
        self.pick_color_button = QPushButton("从图像选择")
        self.pick_color_button.clicked.connect(self.enable_color_picking)
        color_layout.addWidget(self.pick_color_button)
        
        bg_layout.addLayout(color_layout)
        
        # 阈值滑块
        slider_layout = QHBoxLayout()
        slider_layout.addWidget(QLabel("滤除强度:"))
        self.threshold_slider = QSlider(Qt.Horizontal)
        self.threshold_slider.setMinimum(0)
        self.threshold_slider.setMaximum(255)
        self.threshold_slider.setValue(self.bg_threshold)
        self.threshold_slider.valueChanged.connect(self.threshold_changed)
        slider_layout.addWidget(self.threshold_slider)
        self.threshold_label = QLabel(str(self.bg_threshold))
        slider_layout.addWidget(self.threshold_label)
        bg_layout.addLayout(slider_layout)
        
        bg_group.setLayout(bg_layout)
        layout.addWidget(bg_group)
        
        # 按钮
        buttons = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
            Qt.Horizontal, self)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)
        
        self.setLayout(layout)
        
        # 更新控件状态
        self.update_bg_controls()
    
    def update_color_button(self):
        """更新颜色按钮的显示"""
        color = QColor(*self.bg_color)
        self.color_button.setStyleSheet(
            f"background-color: rgb({color.red()}, {color.green()}, {color.blue()})")
        
        # 同步更新文本输入框
        if hasattr(self, 'color_value_edit'):
            self.color_value_edit.setText(f"{self.bg_color[0]},{self.bg_color[1]},{self.bg_color[2]}")
    
    def on_color_text_changed(self, text):
        """处理颜色文本输入变化
        
        参数:
            text (str): 颜色文本值
        """
        try:
            # 尝试解析RGB值
            parts = text.replace(' ', '').split(',')
            if len(parts) == 3:
                r = int(parts[0])
                g = int(parts[1])
                b = int(parts[2])
                
                # 验证RGB值范围
                if 0 <= r <= 255 and 0 <= g <= 255 and 0 <= b <= 255:
                    self.bg_color = [r, g, b]
                    # 只更新按钮样式，避免循环
                    color = QColor(*self.bg_color)
                    self.color_button.setStyleSheet(
                        f"background-color: rgb({color.red()}, {color.green()}, {color.blue()})")
        except:
            pass  # 忽略解析错误
    
    def choose_color(self):
        """打开颜色选择对话框"""
        color = QColorDialog.getColor(QColor(*self.bg_color), self, "选择背景色")
        if color.isValid():
            self.bg_color = [color.red(), color.green(), color.blue()]
            self.update_color_button()
    
    def enable_color_picking(self):
        """启用从图像选择颜色模式"""
        # 隐藏对话框
        self.hide()
        # 通知主窗口放大当前区域并启用颜色选择模式
        main_window = self.parent()
        if main_window:
            # 获取当前区域索引
            region_index = -1
            if self.region_data and len(self.region_data) > 4:
                region_name = self.region_data[4]
                for i, region in enumerate(main_window.region_mgr.regions):
                    if region[4] == region_name:
                        region_index = i
                        break
            
            # 如果找到区域，放大该区域
            if region_index >= 0:
                main_window.canvas.zoom_to_region(region_index)
            
            # 启用颜色选择
            main_window.enable_color_picking(self)
            main_window.statusBar().showMessage("在图像上点击选择背景色")
    
    def on_color_picked(self, color):
        """处理颜色选择完成
        
        参数:
            color (list): RGB颜色值
        """
        self.bg_color = color
        self.update_color_button()
        self.show()  # 重新显示对话框
    
    def threshold_changed(self, value):
        """阈值改变时的处理"""
        self.bg_threshold = value
        self.threshold_label.setText(str(value))
    
    def on_bg_check_changed(self, state):
        """背景滤除复选框状态改变处理"""
        self.enable_bg_removal = state == Qt.Checked
        self.update_bg_controls()
    
    def update_bg_controls(self):
        """更新背景滤除相关控件状态"""
        enabled = self.enable_bg_removal
        self.color_button.setEnabled(enabled)
        self.color_value_edit.setEnabled(enabled)
        self.pick_color_button.setEnabled(enabled)
        self.threshold_slider.setEnabled(enabled)
        self.threshold_label.setEnabled(enabled)
    
    def get_settings(self):
        """获取设置参数
        
        返回:
            dict: 包含区域设置的字典
        """
        if not self.region_data:
            return None
            
        # 注意：名称将由RegionManager自动生成，这里不读取name_edit的值
        return {
            "x": self.x_spin.value(),
            "y": self.y_spin.value(),
            "width": self.w_spin.value(),
            "height": self.h_spin.value(),
            "name": None,  # 名称将由区域管理器自动生成
            "enable_bg_removal": self.enable_bg_removal,
            "bg_color": self.bg_color,
            "bg_threshold": self.bg_threshold
        }

class SaveOptionsDialog(QDialog):
    """保存选项对话框"""
    
    def __init__(self, parent=None):
        """初始化对话框
        
        参数:
            parent (QWidget, optional): 父窗口
        """
        super().__init__(parent)
        
        self.format = "PNG"
        self.include_coordinates = True
        self.remove_background = False
        
        self.init_ui()
    
    def init_ui(self):
        """初始化用户界面"""
        self.setWindowTitle("保存选项")
        self.setMinimumWidth(350)
        
        # 主布局
        layout = QVBoxLayout()
        
        # 格式选择
        format_group = QGroupBox("输出格式")
        format_layout = QVBoxLayout()
        
        self.png_radio = QRadioButton("PNG")
        self.jpg_radio = QRadioButton("JPG")
        self.bmp_radio = QRadioButton("BMP")
        
        self.png_radio.setChecked(True)
        
        format_layout.addWidget(self.png_radio)
        format_layout.addWidget(self.jpg_radio)
        format_layout.addWidget(self.bmp_radio)
        
        format_group.setLayout(format_layout)
        layout.addWidget(format_group)
        
        # 选项
        options_group = QGroupBox("选项")
        options_layout = QVBoxLayout()
        
        self.coords_check = QCheckBox("在文件名中包含坐标信息")
        self.coords_check.setChecked(True)
        options_layout.addWidget(self.coords_check)
        
        self.bg_check = QCheckBox("移除背景色 (仅PNG)")
        options_layout.addWidget(self.bg_check)
        
        options_group.setLayout(options_layout)
        layout.addWidget(options_group)
        
        # 确认按钮
        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        layout.addWidget(button_box)
        
        self.setLayout(layout)
    
    def get_options(self):
        """获取保存选项
        
        返回:
            dict: 包含保存选项的字典
        """
        # 确定格式
        format_type = "PNG"
        if self.jpg_radio.isChecked():
            format_type = "JPEG"
        elif self.bmp_radio.isChecked():
            format_type = "BMP"
        
        return {
            "format": format_type,
            "include_coordinates": self.coords_check.isChecked(),
            "remove_background": self.bg_check.isChecked() and self.png_radio.isChecked()
        }

class BackgroundRemovalDialog(QDialog):
    """背景色移除设置对话框"""
    
    def __init__(self, image, parent=None):
        """初始化对话框
        
        参数:
            image (numpy.ndarray): 要处理的图像
            parent (QWidget): 父窗口
        """
        super().__init__(parent)
        self.image = image
        self.bg_color = [255, 255, 255]  # 默认白色
        self.threshold = 30
        self.preview_image = None
        self.color_picking = False
        
        self.init_ui()
        self.update_preview()
    
    def init_ui(self):
        """初始化用户界面"""
        self.setWindowTitle("背景滤除设置")
        layout = QVBoxLayout()
        
        # 颜色选择部分
        color_group = QGroupBox("背景颜色")
        color_layout = QVBoxLayout()
        
        # 颜色按钮和输入框
        button_layout = QHBoxLayout()
        self.color_button = QPushButton()
        self.color_button.setFixedSize(50, 25)
        self.update_color_button()
        self.color_button.clicked.connect(self.choose_color)
        button_layout.addWidget(self.color_button)
        
        pick_button = QPushButton("从图像选择")
        pick_button.clicked.connect(self.pick_color_from_image)
        button_layout.addWidget(pick_button)
        button_layout.addStretch()
        color_layout.addLayout(button_layout)
        
        # 添加RGB输入框
        rgb_layout = QHBoxLayout()
        rgb_layout.addWidget(QLabel("RGB值:"))
        self.color_value_edit = QLineEdit()
        self.color_value_edit.setPlaceholderText("255,255,255")
        self.color_value_edit.setText(f"{self.bg_color[0]},{self.bg_color[1]},{self.bg_color[2]}")
        self.color_value_edit.textChanged.connect(self.on_color_text_changed)
        rgb_layout.addWidget(self.color_value_edit)
        color_layout.addLayout(rgb_layout)
        
        color_group.setLayout(color_layout)
        
        # 阈值调整部分
        threshold_group = QGroupBox("阈值")
        threshold_layout = QHBoxLayout()
        
        self.threshold_slider = QSlider(Qt.Horizontal)
        self.threshold_slider.setRange(0, 255)
        self.threshold_slider.setValue(self.threshold)
        self.threshold_slider.valueChanged.connect(self.on_threshold_changed)
        
        self.threshold_label = QLabel(str(self.threshold))
        
        threshold_layout.addWidget(self.threshold_slider)
        threshold_layout.addWidget(self.threshold_label)
        threshold_group.setLayout(threshold_layout)
        
        # 预览部分
        preview_group = QGroupBox("预览")
        preview_layout = QVBoxLayout()
        
        self.preview_label = QLabel()
        self.preview_label.setMinimumSize(200, 200)
        preview_layout.addWidget(self.preview_label)
        preview_group.setLayout(preview_layout)
        
        # 按钮部分
        button_box = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel
        )
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        
        # 添加所有组件
        layout.addWidget(color_group)
        layout.addWidget(threshold_group)
        layout.addWidget(preview_group)
        layout.addWidget(button_box)
        
        self.setLayout(layout)
    
    def update_color_button(self):
        """更新颜色按钮显示"""
        # 创建一个颜色图标
        pixmap = QPixmap(50, 25)
        pixmap.fill(QColor(*self.bg_color))
        self.color_button.setIcon(QIcon(pixmap))
        self.color_button.setIconSize(QSize(50, 25))
        
        # 同步更新文本输入框
        if hasattr(self, 'color_value_edit'):
            self.color_value_edit.setText(f"{self.bg_color[0]},{self.bg_color[1]},{self.bg_color[2]}")
    
    def on_color_text_changed(self, text):
        """处理颜色文本输入变化
        
        参数:
            text (str): 颜色文本值
        """
        try:
            # 尝试解析RGB值
            parts = text.replace(' ', '').split(',')
            if len(parts) == 3:
                r = int(parts[0])
                g = int(parts[1])
                b = int(parts[2])
                
                # 验证RGB值范围
                if 0 <= r <= 255 and 0 <= g <= 255 and 0 <= b <= 255:
                    self.bg_color = [r, g, b]
                    # 只更新按钮样式，避免循环
                    color = QColor(*self.bg_color)
                    pixmap = QPixmap(50, 25)
                    pixmap.fill(color)
                    self.color_button.setIcon(QIcon(pixmap))
                    self.color_button.setIconSize(QSize(50, 25))
                    self.update_preview()
        except:
            pass  # 忽略解析错误
    
    def choose_color(self):
        """打开颜色选择对话框"""
        color = QColorDialog.getColor(QColor(*self.bg_color), self)
        if color.isValid():
            self.bg_color = [color.red(), color.green(), color.blue()]
            self.update_color_button()
            self.update_preview()
    
    def pick_color_from_image(self):
        """从图像中选择颜色"""
        self.color_picking = True
        self.hide()  # 隐藏对话框
        
        # 通知主窗口启用颜色选择模式
        main_window = self.parent()
        if main_window:
            main_window.enable_color_picking(self)
            main_window.statusBar().showMessage("请在图像上点击选择背景色")
    
    def on_color_picked(self, color):
        """处理颜色选择完成事件
        
        参数:
            color (list): RGB颜色值
        """
        self.bg_color = color
        self.update_color_button()
        self.update_preview()
        self.show()  # 重新显示对话框
        self.color_picking = False
    
    def on_threshold_changed(self, value):
        """处理阈值变化事件"""
        self.threshold = value
        self.threshold_label.setText(str(value))
        self.update_preview()
    
    def update_preview(self):
        """更新预览图像"""
        if self.image is None:
            return
            
        try:
            # 创建预览图像
            processor = ImageProcessor()
            self.preview_image = processor.remove_background(
                self.image.copy(),
                self.bg_color,
                self.threshold
            )
            
            # 转换为QImage显示
            h, w = self.preview_image.shape[:2]
            bytes_per_line = 4 * w
            
            q_image = QImage(
                self.preview_image.data,
                w, h,
                bytes_per_line,
                QImage.Format_RGBA8888
            )
            
            # 调整大小以适应预览区域
            pixmap = QPixmap.fromImage(q_image)
            scaled_pixmap = pixmap.scaled(
                self.preview_label.size(),
                Qt.KeepAspectRatio,
                Qt.SmoothTransformation
            )
            
            # 显示预览
            self.preview_label.setPixmap(scaled_pixmap)
            
        except Exception as e:
            print(f"更新预览时出错: {str(e)}")
    
    def get_settings(self):
        """获取设置值
        
        返回:
            dict: 包含背景色和阈值的设置字典
        """
        return {
            "bg_color": self.bg_color,
            "threshold": self.threshold
        } 